//--------------------------------------------------------------------------------
// This file is a portion of the D2D1Renderer.  It is distributed
// under the MIT License, available in the root of this distribution and 
// at the following URL:
//
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright (c) Mirco Timmermann
//
//--------------------------------------------------------------------------------
#pragma once


#include "display\DisplayObjectContainer.h"

#include "..\Rendering\canvas\Direct2DContext.h"
#include "..\Rendering\ID2D1FrameRenderListener.h"

#include "..\Objects\IKeyboardListener.h"
#include "..\Objects\IMouseListener.h"

#include <sstream>


namespace D2 {

class Stage : public DisplayObjectContainer, public ID2D1FrameRenderListener, public IKeyboardListener, public IMouseListener {

template <class T>
static inline std::string to_string(const T& t) {
	std::stringstream ss;
	ss << t;
	return ss.str();
}


public:
	Stage();
	~Stage(void);

	virtual void ProcessMouseMessage(RAWMOUSE* mouse, HWND hwnd);

private:
	virtual bool Draw(Direct2DContext* direct2DContext, D2D1::Matrix3x2F* mtx = 0);

//private:
	//Direct2DContext* _direct2DContext;

///////////////////////////////////////////////////////////////////////////////////////////////
//                                   @IKeyboardListener                                      //
///////////////////////////////////////////////////////////////////////////////////////////////
public:
	virtual void IKeyboardListener::_OnKeyUp(unsigned int vkey, unsigned int ckey);
	virtual void IKeyboardListener::_OnKeyDown(unsigned int vkey, unsigned int ckey);

///////////////////////////////////////////////////////////////////////////////////////////////
//                                      @IMouseListener                                      //
///////////////////////////////////////////////////////////////////////////////////////////////
public:
	virtual LRESULT HandleWindowMessage( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam );

	virtual bool IMouseListener::_OnMouseUp(int key, int x, int y);
	virtual bool IMouseListener::_OnMouseDown(int key, int x, int y);
	virtual bool IMouseListener::_OnMouseMove(int key, int x, int y);
	virtual bool IMouseListener::_OnMouseWheel(int key, int wheelDelta, int x, int y);
	virtual bool IMouseListener::_OnMouseDoubleClick(int key, int x, int y);

private:
	/*
	* holds the DisplayObject where the mouse is currently over.
	*/
	DisplayObject* _mouseOverTarget;

	/*
    * holds the DisplayObject on which was last clicked (Mouse down).
    */
    DisplayObject** _focusMouseTarget;

	/*
	*
	*/
	DisplayObject** _activeMouseTarget;

	void testMouseOverDisplayObject(int key, int x, int y);
	void testMouseDownDisplayObject(int key, int x, int y);
	void testMouseUpDisplayObject(int key, int x, int y);
	void testMouseMoveDisplayObject(int key, int x, int y);
	void testMouseDoubleClickDisplayObject(int key, int x, int y);

	bool _shiftKeyPressed;
	bool _strgKeyPressed;
	bool _altKeyPressed;

public:
	virtual void focus(DisplayObject* displayObject);
	virtual void unfocus();

///////////////////////////////////////////////////////////////////////////////////////////////
//                                 MOUSE DISTANCE MEASURE                                    //
///////////////////////////////////////////////////////////////////////////////////////////////
private:
	int _distanceX;
	int _distanceY;

	int _mouseX;
	int _mouseY;

	int _pre_mouseX;
	int _pre_mouseY;

public:
	int GetMouseX();
	int GetMouseY();

private:
	int MapKey(unsigned int key);

///////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                           //
///////////////////////////////////////////////////////////////////////////////////////////////
protected:
	virtual void _bubbleNotifyAdded(DisplayObject* displayObject);
	virtual void _bubbleNotifyRemoved(DisplayObject* displayObject);

///////////////////////////////////////////////////////////////////////////////////////////////
//                                @ID2D1FrameRenderListener                                  //
///////////////////////////////////////////////////////////////////////////////////////////////

public:
	virtual void OnD2D1FrameRender(Direct2DContext* direct2DContext);

////
#ifdef _DEBUG
private:
	bool Stage::DrawOverlay(Direct2DContext* direct2DContext, D2D1::Matrix3x2F* mtx = 0);

	bool _showOverlay;
	DisplayObjectContainer* _overlay;

protected:
	virtual DisplayObject* _getObjectsUnderPoint(int mouseX, int mouseY);

public:
	void AddOverlayDisplayObject(DisplayObject* displayObject);
	void AddOverlayDisplayObjectAt(DisplayObject* displayObject, int index);
	void RemoveOverlayDisplayObject(DisplayObject* displayObject);
	void ShowOverlay(bool show);

#endif

};

}